home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 3 / CD ACTUAL 3.iso / linux / system / ringd-0.000 / ringd-0 / ringd / ringd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-02  |  4.4 KB  |  255 lines

  1. /*    ringd.c by Adam Dace <thekind@tezcat.com>
  2.     Enjoy... */
  3.  
  4. #include <errno.h>
  5. #include <fcntl.h>
  6. #include <signal.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <syslog.h>
  11. #include <termios.h>
  12. #include <time.h>
  13. #include <unistd.h>
  14. #include <sys/file.h>
  15. #include <sys/stat.h>
  16. #include <sys/time.h>
  17. #include <sys/wait.h>
  18. #include "config.h"
  19.  
  20. int tty_open(void);
  21. int modem_reset(void);
  22. int get_rings(int);
  23. void shut_down(int);
  24.  
  25. int fd_modem, rings=0;
  26. char buf[32];
  27. time_t timer1;
  28.  
  29. int main(void)
  30. {
  31.         int got_rings;
  32.         pid_t pid;
  33.  
  34.     if ((pid = fork()) < 0)
  35.     {
  36.         perror("Couldn't fork() daemon process");
  37.         return(-1);
  38.     }
  39.     else
  40.         if (pid != 0)
  41.             exit(0);
  42.  
  43.     /* From here on out, it's daemon all the way... */
  44.  
  45.     setsid();
  46.     chdir("/");
  47.     umask(0);
  48.     close(STDIN_FILENO);
  49.     close(STDOUT_FILENO);
  50.     close(STDERR_FILENO);
  51.  
  52.     if (signal(SIGTERM, shut_down) == SIG_ERR)
  53.     {
  54.         syslog(LOG_ERR,strerror(errno));
  55.         shut_down(-1);
  56.     }
  57.  
  58.     openlog("ringd", LOG_PID, LOG_DAEMON);
  59.     syslog(LOG_NOTICE, "ringd 0.8 monitoring modem");
  60.  
  61.     while (1)
  62.     {
  63.         got_rings = 0;
  64.  
  65.         while (tty_open() < 0)
  66.         {
  67.             close (fd_modem);
  68.             sleep (RECYCLE_TIME);
  69.         }
  70.  
  71.         if (modem_reset() < 0)
  72.             shut_down(-1);
  73.  
  74.         while (!got_rings)
  75.         {
  76.             timer1 = 0;
  77.             time(&timer1);
  78.  
  79.             if (get_rings(3) < 0)
  80.             {
  81.                 rings=1;
  82.                 continue;
  83.             }
  84.             else
  85.                 rings=0;
  86.  
  87.             if (get_rings(2) < 0)
  88.             {
  89.                 rings=1;
  90.                 continue;
  91.             }
  92.             else
  93.                 rings=0;
  94.  
  95.             got_rings=1;
  96.         }
  97.  
  98.         if (close(fd_modem) < 0)
  99.         {
  100.             syslog(LOG_ERR,strerror(errno));
  101.             shut_down(-1);
  102.         }
  103.  
  104.         sleep(2);
  105.  
  106.         if ((pid=fork()) < 0)    /* Be a man and fork, he says... */
  107.         {            /* What utter crap and pain. */
  108.             syslog(LOG_ERR,strerror(errno));
  109.             shut_down(-1);
  110.         }
  111.         else
  112.             if (pid == 0)    
  113.                     execl(PROGRAM,PROGRAM,ARG,NULL);
  114.             else
  115.                 wait(NULL);
  116.  
  117.         sleep(2);
  118.     }
  119. }
  120.  
  121.  
  122. int tty_open(void) /* Opens the modem, and sets terminal attributes. */
  123. {
  124.     struct termios term;
  125.  
  126.     if ((fd_modem = open("/dev/modem", O_RDWR | O_NOCTTY)) < 0)
  127.     {
  128.         syslog(LOG_ERR,strerror(errno));
  129.         shut_down(-1);
  130.     }
  131.  
  132.     if (isatty(fd_modem) == 0)
  133.     {
  134.         syslog(LOG_ERR,strerror(errno));
  135.         shut_down(-1);
  136.     }
  137.  
  138.     if (flock(fd_modem,LOCK_EX) < 0)
  139.     {
  140.         syslog(LOG_ERR,strerror(errno));
  141.         shut_down(-1);
  142.     }
  143.  
  144.     /* This right here is such a hack, even I have a hard time believing
  145.      * it.  I stole these values from kermit and stty -a.  I tried a
  146.      * number of other combinations, which didn't work, some help here
  147.      * would be greatly appreciated. */
  148.  
  149.     term.c_cflag = CS8 | CREAD | HUPCL | CLOCAL;
  150.     term.c_iflag = IGNBRK | IGNPAR;
  151.     term.c_lflag = 0;
  152.     term.c_oflag = 0;
  153.  
  154.     if (cfsetispeed(&term,BPS_RATE) < 0)
  155.         return(-1);
  156.     if (cfsetospeed(&term,BPS_RATE) < 0)
  157.         return(-1);
  158.  
  159.     if (tcsetattr(fd_modem, TCSANOW, &term) < 0)
  160.         return(-1);
  161.  
  162.     return(0);
  163. }
  164.  
  165. int modem_reset(void) /* Resets the modem, and checks for additional rings. */
  166. {
  167.         char command[]=RESET_STR;         /* Modem reset. */
  168.     int number;
  169.  
  170.         if (write(fd_modem, &command, 4) < 0)
  171.     {
  172.                 syslog(LOG_ERR,strerror(errno));
  173.                 shut_down(-1);
  174.     }
  175.  
  176.         sleep(RING_TIME);
  177.  
  178.         number=read(fd_modem, &buf, 32);
  179.     buf[number]='\0';
  180.  
  181.         if (strstr(buf, OK) == NULL)
  182.     {
  183.                 syslog(LOG_ERR,strerror(errno));
  184.                 shut_down(-1);
  185.     }
  186.  
  187.         if (strstr(buf, RING) != NULL )
  188.                 return (1);
  189.  
  190.     return (0);
  191. }
  192.  
  193. int get_rings(int rings_wanted) /* Waits for a number of specified rings. */
  194. {
  195.     int counter=0, done=0;
  196.     time_t time1=0, time2=0;
  197.     fd_set myset;
  198.  
  199.     FD_ZERO(&myset);
  200.  
  201.     while (!done)  /* BTW, read() is slightly broken, so select() we go */
  202.     {
  203.         FD_SET(fd_modem, &myset);
  204.         select(2,&myset,NULL,&myset,NULL);
  205.  
  206.         counter = read(fd_modem, &buf, 256);
  207.         buf[counter]='\0';
  208.  
  209.         if ((counter > 0) && (strstr(buf, RING) != NULL))
  210.         {
  211.                     time(&time1);
  212.  
  213.             if ((time2 == 0) && ((abs(difftime(timer1, time1)) < TOTAL_TIME)))
  214.             {
  215.                 rings++;
  216.                 time2 = time1;
  217.             }
  218.             else
  219.             {
  220.                 if (((abs(difftime(time1, time2))) < RING_TIME) &&
  221.                     ((abs(difftime(timer1, time2))) < TOTAL_TIME))
  222.                 {
  223.                     rings++;
  224.                     time2 = time1;
  225.                 }
  226.                 else
  227.                     return(-1);
  228.             }
  229.         }
  230.  
  231.         if (rings == rings_wanted)
  232.         {
  233.             if (modem_reset() == 0)
  234.                 done=1;
  235.             else
  236.                 return(-1);
  237.         }
  238.     }
  239.  
  240.     return(0);
  241. }
  242.  
  243. void shut_down(int status)    /* Shut down somewhat gracefully. */
  244. {
  245.     if (status != SIGTERM)
  246.         syslog(LOG_NOTICE,"internal error occured, shutting down");
  247.     else
  248.         syslog(LOG_NOTICE,"SIGTERM recieved, shutting down");
  249.  
  250.     closelog();
  251.     flock(fd_modem,LOCK_UN);
  252.     close(fd_modem);
  253.     exit(status);
  254. }
  255.